package com.demo.web.common;

import com.demo.common.Constants;
import com.demo.dto.BaseResult;
import com.demo.entity.Ads;
import com.demo.entity.SalePerson;
import com.demo.entity.StatisticShare;
import com.demo.entity.UserWx;
import com.demo.service.ISalePersonService;
import com.demo.service.IStatisticShareService;
import com.demo.service.IUserWxService;
import com.demo.vo.SalePersonVo;
import com.demo.wx.AdvancedUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Created by byte2 on 2017-03-29.
 */
@Controller
public class WxController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ISalePersonService spService;
    @Autowired
    private IUserWxService uxService;
    @Autowired
    private IStatisticShareService shareService;

    /**
     * 创建
     *
     * @return
     */
    @RequestMapping(value = "/wx/login")
    public String create(Ads arg, HttpSession session) {
        try {
            logger.debug("[path===================]" + arg.getUrl());
            String path = Constants.domain + "/api/wx/auth";
            if (arg.getUrl() != null) {
                path += "?path=" + AdvancedUtil.urlEncodeUTF8(arg.getUrl());
            }
            return "redirect:" + AdvancedUtil.getRequestCodeUrl(AdvancedUtil.urlEncodeUTF8(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @ResponseBody
    @RequestMapping(value = "/wx/wx-jssdk-config", method = {RequestMethod.GET})
    public BaseResult wxJsSdk(Ads arg, String url) {
        return new BaseResult(true, AdvancedUtil.getParam(url));
    }

    String TAG = "CoreServlet";

    /***
     * 为用户验证第三方服务器使用
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/wx/get", method = {RequestMethod.GET, RequestMethod.POST})
    public void get(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 设置编码
        req.setCharacterEncoding("utf-8");
        //        resp.setContentType("html/text;charset=utf-8");
        resp.setCharacterEncoding("utf-8");
        // 获取输出流
        PrintWriter printWriter = resp.getWriter();

        // 设置一个全局的token,开发者自己设置。api这样解释：Token可由开发者可以任意填写，
        // 用作生成签名（该Token会和接口URL中包含的Token进行比对，从而验证安全性）
        String token = "H5aUhFmiExrbM6Sq2GtAWHH";
        // 根据api说明，获取上述四个参数
        String signature = req.getParameter("signature");
        String timestamp = req.getParameter("timestamp");
        String nonce = req.getParameter("nonce");
        String echostr = req.getParameter("echostr");
        // // temp:临时打印，观看返回参数情况
        System.out.println(TAG + ":signature:" + signature + ",timestamp:" + timestamp + ",nonce:" + nonce + ",echostr:" + echostr);
        // 根据api所说的“加密/校验流程”进行接入。共计三步

        // 第一步:将token、timestamp、nonce三个参数进行字典序排序
        String[] parms = new String[]{token, timestamp, nonce};// 将需要字典序排列的字符串放到数组中
        Arrays.sort(parms);// 按照api要求进行字典序排序
        // 第二步:将三个参数字符串拼接成一个字符串进行sha1加密
        // 拼接字符串
        String parmsString = "";// 注意，此处不能=null。
        for (int i = 0; i < parms.length; i++) {
            parmsString += parms[i];
        }
        // sha1加密
        String mParms = null;// 加密后的结果
        MessageDigest digest = null;
        try {
            digest = java.security.MessageDigest.getInstance("SHA");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        digest.update(parmsString.getBytes());
        byte messageDigest[] = digest.digest();
        // Create Hex String
        StringBuffer hexString = new StringBuffer();
        // 字节数组转换为 十六进制 数
        for (int i = 0; i < messageDigest.length; i++) {
            String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
            if (shaHex.length() < 2) {
                hexString.append(0);
            }
            hexString.append(shaHex);
        }
        mParms = hexString.toString();// 加密结果
        /*
         * api要求： 若确认此次GET请求来自微信服务器，请原样返回echostr参数内容， 则接入生效， 成为开发者成功，否则接入失败。
         */
        // 第三步： 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信接入成功。
        System.out.println(TAG + ":" + mParms + "---->" + signature);
        if (mParms.equals(signature)) {
            System.out.println(TAG + ":" + mParms + "---->" + signature);
            printWriter.write(echostr);
//            printWriter.write("echostr:" + echostr);
        } else {
            // 接入失败,不用回写
            System.out.println(TAG + "接入失败");
        }
    }

    //    @ResponseBody
    @RequestMapping(value = "/wx/auth")
    public String auth(HttpServletRequest request, String code, String path, HttpSession session) throws IOException, URISyntaxException {
        if (code == null) { //微信授权未允许
            return "redirect:" + Constants.domain + "/";
        }
        Map<String, String> data = new HashMap();
        AdvancedUtil advancedUtil = new AdvancedUtil();
        Map<String, String> result = advancedUtil.getUserInfoAccessToken(code.toString(), Constants.LOGIN_TYPE_WX);//通过这个code获取access_token
        if (path != null) {
            Map map = Constants.toMap(path);
            if (map.get("no") != null) {
                StatisticShare ss = shareService.selectByNo(map.get("no").toString());
                if (ss != null && ss.getSharer() != null) {
                    logger.debug("[PATH_NO]" + ss.getSharer());
                    session.setAttribute(Constants.SHARE, ss.getSharer());
                }
            }
        }
        String openId = result.get("openid");
        if (StringUtils.isNotEmpty(openId)) {
            Map<String, String> userInfo = advancedUtil.getUserInfo(result.get("access_token"), openId);//使用access_token获取用户信息
            UserWx uw = new UserWx();
            uw.setOpenid(userInfo.get("openid"));
            uw.setUnionid(userInfo.get("unionid"));
            uw.setProvince(userInfo.get("province"));
            uw.setCity(userInfo.get("city"));
            uw.setNickName(userInfo.get("nickname"));
            uw.setHeadimgurl(userInfo.get("headimgurl"));
            uw.setUnitid(Constants.WXUserTypeWX); //标记公众号应用用户
            UserWx ux = uxService.selectByOpenid(uw.getOpenid());
            SalePerson sp = spService.selectByOpenid(uw.getUnionid());
            if (ux != null && sp != null) {
                session.setAttribute(Constants.CURRENT_SP, sp);
                return "redirect:" + Constants.domain + "/wx/index.html";
            } else if (ux != null && sp == null) {
                session.setAttribute(Constants.CURRENT_WX_USER, uw);
                return "redirect:" + Constants.domain + "/wx/login-validate.html"; // -> validate phone
            } else if (ux == null && sp != null) {
                uxService.insertSelective(uw);
                session.setAttribute(Constants.CURRENT_SP, sp);
                return "redirect:" + Constants.domain + "/wx/index.html";
            } else {
                uxService.insertSelective(uw);
                session.setAttribute(Constants.CURRENT_WX_USER, uw);
                return "redirect:" + Constants.domain + "/wx/login-validate.html"; // -> validate phone
            }


//            if (ux == null) {
//                if (uw.getUnionid() != null && sp == null) {
//                    session.setAttribute(Constants.CURRENT_WX_USER, uw);
//                    int uw_res = uxService.insertSelective(uw);
//                    return "redirect:" + Constants.domain + "/wx/login-validate.html"; // -> validate phone
//                } else if (sp != null && uw.getUnionid() != null) {
//                    uxService.insertSelective(uw);
//                    session.setAttribute(Constants.CURRENT_SP, sp);
//                    return "redirect:" + Constants.domain + "/wx/index.html"; //跳转至首页
//                }
//            } else if (sp == null) {
//                return "redirect:" + Constants.domain + "/wx/login-validate.html"; // -> validate phone
//            } else {
//                session.setAttribute(Constants.CURRENT_SP, sp);
//                if (path != null) {
//                    return "redirect:" + java.net.URLDecoder.decode(path, "UTF-8"); // -> index.html
//                }
//                return "redirect:" + Constants.domain + "/wx/index.html"; // -> index.html
//            }
        }
        return "redirect:" + Constants.domain + "/wx/index.html"; //跳转至首页
    }

    /**
     * web pc 授权登录
     *
     * @param request
     * @param code
     * @param session
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/web/auth")
    public String webAuth(HttpServletRequest request, String code, String path, HttpSession session) throws IOException, URISyntaxException {
        Map<String, String> data = new HashMap();
        AdvancedUtil advancedUtil = new AdvancedUtil();
        Map<String, String> result = advancedUtil.getUserInfoAccessToken(code.toString(), Constants.LOGIN_TYPE_PC);//通过这个code获取access_token
        String openId = result.get("openid");
        if (path != null) {
            Map map = Constants.toMap(path);
            if (map.get("no") != null) {
                StatisticShare ss = shareService.selectByNo(map.get("no").toString());
                if (ss != null && ss.getSharer() != null) {
                    session.setAttribute(Constants.SHARE, ss.getSharer());
                }
            }
        }

        if (StringUtils.isNotEmpty(openId)) {
            logger.debug("try getting user info. [openid={}]", openId);
            Map<String, String> userInfo = advancedUtil.getUserInfo(result.get("access_token"), openId);//使用access_token获取用户信息
            UserWx uw = new UserWx();
            uw.setOpenid(userInfo.get("openid"));
            uw.setUnionid(userInfo.get("unionid"));
            uw.setProvince(userInfo.get("province"));
            uw.setCity(userInfo.get("city"));
            uw.setNickName(userInfo.get("nickname"));
            uw.setHeadimgurl(userInfo.get("headimgurl"));
//            uw.setUnitid(Constants.WXUserTypeWX); //标记网站应用公众号应用用户
//            UserWx ux = uxService.selectByUnionid(uw);
            UserWx ux = uxService.selectByOpenid(uw.getOpenid());
            SalePerson sp = spService.selectByOpenid(uw.getUnionid());
            if (ux == null) {
                uw.setUnitid(Constants.WXUserTypePC);
                session.setAttribute(Constants.CURRENT_WX_USER, uw);
                int uw_res = uxService.insertSelective(uw);
            } else {
                if (ux.getUnitid() == null) {
                    ux.setUnitid(Constants.WXUserTypePC);
                    uxService.updateByPrimaryKeySelective(ux);
                }
            }
            if (sp == null) {
                return "redirect:" + Constants.domain + "/login-validate.html"; // -> validate phone
            } else {
                session.setAttribute(Constants.CURRENT_SP, sp);
                if (path != null) {
                    return "redirect:" + java.net.URLDecoder.decode(path, "UTF-8"); // -> index.html
                }
                return "redirect:" + Constants.domain + "/index.html"; // -> index.html
            }

        }
        return "redirect:" + Constants.domain + "/index.html"; //跳转至首页
    }


    public String getProperty(String key) throws IOException {
        Resource resource = new ClassPathResource("config/config.properties");
        Properties properties = new Properties();
        properties.load(resource.getInputStream());
        return properties.getProperty(key);
    }

    /**
     * 短信验证码
     *
     * @param arg
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/wx/valid-phone")
    public BaseResult<Object> valid(SalePersonVo arg, HttpSession session) {
        if (!arg.getCode().equals(session.getAttribute(Constants.PHONE_CODE))) {
            return new BaseResult(false, "短信验证码不正确!", 403);
        }
        UserWx uw = (UserWx) session.getAttribute(Constants.CURRENT_WX_USER);
        Object sharer = session.getAttribute(Constants.SHARE);
        if (sharer != null) {
            String share = (String) sharer;
            logger.debug("[PATH_NO==============]" + share);
            arg.setUserId(share); //
//            SalePerson sp = spService.selectByPrimaryKey(Integer.valueOf(share));
//            sp.setSalesCount(sp.getSalesCount() + 1);
//            spService.updateByPrimaryKeySelective(sp);
        }
        arg.setOpenid(uw.getUnionid());
        arg.setAvatar(uw.getHeadimgurl());
        arg.setUserName(uw.getNickName());
        arg.setPhoneValid("1"); //手机号已验证
        Object res = spService.registerByShare(arg);
        if ((res instanceof String)) {
            return new BaseResult(false, res.toString(), 403);
        } else if ((res.equals(new Integer(1)))) {
            SalePerson sp = spService.selectByOpenid(uw.getUnionid()); // 通过unionid登录
            session.setAttribute(Constants.CURRENT_SP, sp);
            return new BaseResult(true, "success!");
        } else {
            return new BaseResult(false, "验证失败!", 403);
        }
    }


}
